/*
This file is part of [ahttpserver] project. 

Author: Artem Kustikov (kustikoff[at]tut.by)


This code is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this code.

Permission is granted to anyone to use this code for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this code must not be misrepresented; you must
not claim that you wrote the original code. If you use this
code in a product, an acknowledgment in the product documentation
would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original code.

3. This notice may not be removed or altered from any source
distribution.
*/


#ifndef AHTTPSERVER_SETTINGS_LOADER_H
#define AHTTPSERVER_SETTINGS_LOADER_H

#include "aconnect/types.hpp"
#include "ahttp/http_server_settings.hpp"
#include "tinyxml/tinyxml.h"

using ahttp::settings_load_error;

namespace DefaultFiles
{
	aconnect::string_constant ConfigFileName = "server.config";
	aconnect::string_constant DirectoryConfigFile = "directory.config";
	aconnect::string_constant MessagesConfigFile = "messages.config";
	aconnect::string_constant PluginsDirectory = "plugins";
	aconnect::string_constant LogFileTemplate = "{app-path}log/{timestamp}.log";

#ifdef WIN32
	aconnect::string_constant PluginExtension = ".dll";
#else
	aconnect::string_constant PluginExtension = ".so";
#endif

};


class SettingsLoader
{


public:
	SettingsLoader ();

	void loadFile (aconnect::string configFilePath) throw (settings_load_error);

	void loadLoggerSettings () throw (settings_load_error);

	void load (ahttp::HttpServerSettings& settings, bool firstLoad) throw (settings_load_error);

	template<typename T>
	static bool loadIntAttribute (class TiXmlElement* elem, 
		aconnect::string_constptr attr, T &value);

	static bool loadBoolAttribute (class TiXmlElement* elem, 
		aconnect::string_constptr attr, bool &value);

	static bool loadTristateAttribute (class TiXmlElement* elem, 
		aconnect::string_constptr attr, ahttp::Tristate::TristateEnum &value);
			
	static bool loadStringAttribute (class TiXmlElement* elem, 
		aconnect::string_constptr attr, aconnect::string &value, bool cannotBeEmpty = false);

	
public:
	//==================================================================//
	//	Simple properties												//
	//==================================================================//
	
	inline const aconnect::Log::LogLevel logLevel() const					{		return _logLevel;				}
	inline const aconnect::string logFileTemplate() const					{		return _logFileTemplate;		}
	inline const size_t	maxLogFileSize() const								{		return _maxLogFileSize;			}
	
	inline const aconnect::string configFilePath() const					{		return _configFilePath;			}
	

protected:

		void loadServerSettings (ahttp::HttpServerSettings& settings, class TiXmlElement* serverElem) throw (settings_load_error);

		void loadMessages (ahttp::HttpServerSettings& settings) throw (settings_load_error);

		void loadMimeTypes (ahttp::HttpServerSettings& settings, class TiXmlElement* mimeTypesElement) throw (settings_load_error);

		void loadPlugins (ahttp::HttpServerSettings& settings, class TiXmlElement* pluginsElement, ahttp::PluginType pluginType) throw (settings_load_error);

		aconnect::string loadPluginRegistration (ahttp::HttpServerSettings& settings, class TiXmlElement* pluginElem, ahttp::PluginInfo& info, ahttp::PluginType pluginType) throw (settings_load_error);

		ahttp::DirectorySettings loadDirectory (ahttp::HttpServerSettings& settings, class TiXmlElement* dirElement) throw (settings_load_error);

		/// Now loads only plugins, mappings, default-documents
		void loadDirectorySettings (ahttp::HttpServerSettings& settings, class TiXmlElement* dirElement, ahttp::DirectorySettings& dirInfo) throw (settings_load_error);

		void loadDirectoryIndexDocuments (class TiXmlElement* documentsElement, ahttp::DirectorySettings& dirInfo) throw (settings_load_error);
		
		void loadDirectoryPlugins (ahttp::HttpServerSettings& settings, class TiXmlElement* pluginsElement, ahttp::DirectorySettings& dirInfo, ahttp::PluginType type) throw (settings_load_error);
		
		void loadDirectoryMappings (class TiXmlElement* mappingsElement, ahttp::DirectorySettings& dirInfo) throw (settings_load_error);

		void tryLoadLocalSettings (ahttp::HttpServerSettings& settings, aconnect::string_constref filePath, ahttp::DirectorySettings& dirInfo) throw (settings_load_error);

		void checkLocalSettingsFilePresence (ahttp::DirectorySettings*) throw (settings_load_error);
		
protected:
	
	aconnect::string	_directoryConfigFile;
	aconnect::string	_messagesFile;
	aconnect::string	_pluginsDirectory;

	aconnect::string	_appLocaton;
	aconnect::string	_configFilePath;
	TiXmlDocument		_xmlDocument;

	// logger
	aconnect::Log::LogLevel _logLevel;
	aconnect::string		_logFileTemplate;
	size_t					_maxLogFileSize;
};




#endif // AHTTPSERVER_SETTINGS_LOADER_H
